home *** CD-ROM | disk | FTP | other *** search
- /* Momentum.c
- **
- ** Copyright 1995, mFactory, Inc.
- ** All rights reserved.
- */
-
- #include "Momentum.h"
-
- #define kActivatePopup 6 // DITL indices
- #define kTerminatePopup 8
- #define kMassField 17
- #define kAngleField 13
- #define kMagnitudeField 15
- #define kTermVelField 19
-
- #define kGravServID ((CompID *) "Gravity\0\0\0\0\0\0\0\0\0") // service MOM ID
-
- #define massAttrib ((CompID *) "mass\0\0\0\0\0\0\0\0\0\0\0\0") // attributes
- #define angleAttrib ((CompID *) "initialangle\0\0\0\0")
- #define magnitudeAttrib ((CompID *) "initialmagnitude")
- #define resVectorAttrib ((CompID *) "resultantvector\0")
-
- #define kTimePeriod 1 // milliseconds
-
- static double pi = 3.14159;
-
-
- /* Initial entry point
- */
-
- MCompMainFuncDcl MCompMainName(MInitInfo *initInfo)
- {
- MDefineComponent(MomentumComp, kMCanDragOff);
- MInheritClass(MComponent, kMCompNumProcs, kMBaseCompSlot);
-
- // MComponent methods we must override
-
- MDefineMethod(kMomentumSlot, kMBaseCompSlot, kMCompConstructor, MCompConstructor);
- MDefineMethod(kMomentumSlot, kMBaseCompSlot, kMCompCopy, MCompCopy);
- MDefineMethod(kMomentumSlot, kMBaseCompSlot, kMCompCopyConstructor, MCompCopyConstructor);
- MDefineMethod(kMomentumSlot, kMBaseCompSlot, kMCompDestructor, MCompDestructor);
-
- // MComponent methods we choose to override
-
- MDefineMethod(kMomentumSlot, kMBaseCompSlot, kMCompEditorOpen, MCompEditorOpen);
- MDefineMethod(kMomentumSlot, kMBaseCompSlot, kMCompEditorAccept, MCompEditorAccept);
-
- MDefineMethod(kMomentumSlot, kMBaseCompSlot, kMCompGetSaveInfo, MCompGetSaveInfo);
- MDefineMethod(kMomentumSlot, kMBaseCompSlot, kMCompSaveComponent, MCompSaveComponent);
- MDefineMethod(kMomentumSlot, kMBaseCompSlot, kMCompRestoreComponent, MCompRestoreComponent);
-
- MDefineMethod(kMomentumSlot, kMBaseCompSlot, kMCompProcessMessage, MCompProcessMessage);
-
- MDefineMethod(kMomentumSlot, kMBaseCompSlot, kMCompGetAttribute, MCompGetAttribute);
- MDefineMethod(kMomentumSlot, kMBaseCompSlot, kMCompSetAttribute, MCompSetAttribute);
-
- MDefineMethod(kMomentumSlot, kMBaseCompSlot, kMCompAdaptIDs, MCompAdaptIDs);
-
- // Define our own methods
-
- MDefineMethod(kMomentumSlot, kMomentumSlot, kMomentumTask, MomentumTask);
-
- MConnectCommonServices(initInfo);
-
- MEndComponentDef;
- }
-
-
- /* Initialize component
- */
-
- static MErr MCompConstructor(MomentumComp *self, MObjectRef *mRef)
- {
- MInitEvent(self->f_activateEvent, kMParentEnabled, 0);
- MInitEvent(self->f_terminateEvent, kMNone, 0);
- MInitDouble(self->f_mass, 5000.0);
- MInitDouble(self->f_initialAngle, 0.0);
- MInitDouble(self->f_initialMagnitude, 0.0);
- MInitDouble(self->f_terminalVelocity, 10.0);
- return kMNoCompErr;
- }
-
-
- /* Copy component data
- */
-
- static MErr MCompCopy(MomentumComp *self, MomentumComp *previousSelf)
- {
- MCopyEvent(self->f_activateEvent, previousSelf->f_activateEvent);
- MCopyEvent(self->f_terminateEvent, previousSelf->f_terminateEvent);
- MCopyDouble(self->f_mass, previousSelf->f_mass);
- MCopyDouble(self->f_initialAngle, previousSelf->f_initialAngle);
- MCopyDouble(self->f_initialMagnitude, previousSelf->f_initialMagnitude);
- MCopyDouble(self->f_terminalVelocity, previousSelf->f_terminalVelocity);
- return kMNoCompErr;
- }
-
-
- /* Copy component
- */
-
- static MErr MCompCopyConstructor(MomentumComp *self, MomentumComp *previousSelf, MObjectRef *mRef)
- {
- MCompConstructor(self, mRef);
- return MCompCopy(self, previousSelf);
- }
-
-
- /* Dispose component
- */
-
- static MErr MCompDestructor(MomentumComp *self)
- {
- MDisposeEvent(self->f_activateEvent);
- MDisposeEvent(self->f_terminateEvent);
- MDisposeDouble(self->f_mass);
- MDisposeDouble(self->f_initialAngle);
- MDisposeDouble(self->f_initialMagnitude);
- MDisposeDouble(self->f_terminalVelocity);
- return kMNoCompErr;
- }
-
-
- /* Open component dialog
- */
-
- static MErr MCompEditorOpen(MomentumComp *self, void *editor, short editorType)
- {
- if ( editorType == kMDialogEditorType ) {
- MSetEditorItem(editor, kActivatePopup, (MDataType *) &self->f_activateEvent);
- MSetEditorItem(editor, kTerminatePopup, (MDataType *) &self->f_terminateEvent);
- MSetEditorItem(editor, kMassField, (MDataType *) &self->f_mass);
- MSetEditorItem(editor, kAngleField, (MDataType *) &self->f_initialAngle);
- MSetEditorItem(editor, kMagnitudeField, (MDataType *) &self->f_initialMagnitude);
- MSetEditorItem(editor, kTermVelField, (MDataType *) &self->f_terminalVelocity);
- return kMNoCompErr;
- } else
- return kMUnableToComplyCompErr;
- }
-
-
- /* Close component dialog
- */
-
- static MErr MCompEditorAccept(MomentumComp *self, void *editor)
- {
- MGetEditorItem(editor, kActivatePopup, (MDataType *) &self->f_activateEvent);
- MGetEditorItem(editor, kTerminatePopup, (MDataType *) &self->f_terminateEvent);
- MGetEditorItem(editor, kMassField, (MDataType *) &self->f_mass);
- MGetEditorItem(editor, kAngleField, (MDataType *) &self->f_initialAngle);
- MGetEditorItem(editor, kMagnitudeField, (MDataType *) &self->f_initialMagnitude);
- MGetEditorItem(editor, kTermVelField, (MDataType *) &self->f_terminalVelocity);
- return kMNoCompErr;
- }
-
-
- /* Provide save information
- */
-
- static MErr MCompGetSaveInfo(MomentumComp *self, MFileIOServ *file, long saveInfo, short *rev, long *len)
- {
- long valueSize;
-
- MSizeOfValue(file, &self->f_activateEvent, &valueSize);
- *len = valueSize;
- MSizeOfValue(file, &self->f_terminateEvent, &valueSize);
- *len += valueSize;
- MSizeOfValue(file, &self->f_mass, &valueSize);
- *len += valueSize;
- MSizeOfValue(file, &self->f_initialAngle, &valueSize);
- *len += valueSize;
- MSizeOfValue(file, &self->f_initialMagnitude, &valueSize);
- *len += valueSize;
- MSizeOfValue(file, &self->f_terminalVelocity, &valueSize);
- *len += valueSize;
-
- *rev = kMomentumRev;
- return kMNoCompErr;
- }
-
-
- /* Save component
- */
-
- static MErr MCompSaveComponent(MomentumComp *self, MFileIOServ *file, long saveInfo)
- {
- MWriteValue(file, &self->f_activateEvent);
- MWriteValue(file, &self->f_terminateEvent);
- MWriteValue(file, &self->f_mass);
- MWriteValue(file, &self->f_initialAngle);
- MWriteValue(file, &self->f_initialMagnitude);
- MWriteValue(file, &self->f_terminalVelocity);
-
- return kMNoCompErr;
- }
-
-
- /* Restore component
- */
-
- static MErr MCompRestoreComponent(MomentumComp *self, MFileIOServ *file, long saveInfo, short rev)
- {
- if ( rev == kMomentumRev ) {
- MReadValue(file, &self->f_activateEvent);
- MReadValue(file, &self->f_terminateEvent);
- MReadValue(file, &self->f_mass);
- MReadValue(file, &self->f_initialAngle);
- MReadValue(file, &self->f_initialMagnitude);
- MReadValue(file, &self->f_terminalVelocity);
- return kMNoCompErr;
- }
- else
- return kMUnableToComplyCompErr;
- }
-
-
- /* Process incoming message
- */
-
- static MErr MCompProcessMessage(MomentumComp *self, MMessagePtr message)
- {
- if ( MDetectMessage(message, self->f_activateEvent) ) {
- MService *gravServ;
-
- MGetService(self, kGravServID, kMAnyInstance, kMSpawnIfNotFound, &gravServ);
- if ( MError() == kMNoCompErr ) {
- long globalTime;
- double radians, cosVal, sinVal;
-
- MAddClient(gravServ, self);
- MPostCTimeTask(self, nil, kTimePeriod, kMomentumSlot, kMomentumTask);
-
- MGetGlobalTime(&globalTime);
- self->f_timeStamp = globalTime;
- self->f_accelerationX = self->f_accelerationY = 0.0;
-
- self->f_fractionalX = 0.0;
- self->f_fractionalY = 0.0;
-
- radians = self->f_initialAngle.f_value * pi / 180.0;
- MCos(&cosVal, radians);
- MSin(&sinVal, radians);
- self->f_velocityX = self->f_initialMagnitude.f_value * cosVal;
- self->f_velocityY = -(self->f_initialMagnitude.f_value * sinVal);
- }
- return kMNoCompErr;
- }
- else if ( MDetectMessage(message, self->f_terminateEvent) || MDetectDisableMessage(message) ) {
- MService *gravServ;
-
- MGetService(self, kGravServID, kMAnyInstance, kMSpawnIfNotFound, &gravServ);
- if ( MError() == kMNoCompErr )
- MDeleteClient(gravServ, self);
- MKillCTimeTask(self, nil);
- return kMNoCompErr;
- }
- else
- return kMUnableToComplyCompErr;
- }
-
-
- /* Get component attribute
- */
-
- static MErr MCompGetAttribute(MomentumComp *self, MomID attribName, MDataType *selector, MDataType *dataValue)
- {
- if ( MCmpMomID(attribName, kMPositionAttrib) ) {
- MObjectRef *element;
- MPoint2D position;
-
- MGetElement(&element);
- MGetElementAttribute(element, kMPositionAttrib, NULL, dataValue);
-
- MInitPoint2D(position, dataValue->f_point.f_value.PNTX, dataValue->f_point.f_value.PNTY);
- MInitVector2D(dataValue->f_vector, position.f_value.PNTX + self->f_fractionalX, position.f_value.PNTY + self->f_fractionalY);
- return kMNoCompErr;
- }
- else if ( MCmpMomID(attribName, kMSizeAttrib) ) {
- MObjectRef *element;
-
- MGetElement(&element);
- MGetElementAttribute(element, kMSizeAttrib, NULL, dataValue);
- return kMNoCompErr;
- }
- else if ( MCmpMomID(attribName, massAttrib) ) {
- dataValue->f_double = self->f_mass;
- return kMNoCompErr;
- }
- else if ( MCmpMomID(attribName, kMEventsAttrib) && selector &&
- selector->f_type.f_type == kMInteger ) {
- switch (selector->f_integer.f_value & ~kMEventMask) {
- case kMEventExecute:
- if ( (selector->f_integer.f_value & kMEventMask) == 1 ) {
- MCopyEvent(dataValue->f_event, self->f_activateEvent);
- return kMNoCompErr;
- }
- else
- return kMUnableToComplyCompErr;
-
- case kMEventTerminate:
- if ( (selector->f_integer.f_value & kMEventMask) == 1 ) {
- MCopyEvent(dataValue->f_event, self->f_terminateEvent);
- return kMNoCompErr;
- }
- else
- return kMUnableToComplyCompErr;
-
- default:
- return kMUnableToComplyCompErr;
- }
- }
- else
- return kMUnableToComplyCompErr;
- }
-
-
- /* Set component attribute
- */
-
- static MErr MCompSetAttribute(MomentumComp *self, MomID attribName, MDataType *selector, MDataType *dataValue)
- {
- if ( MCmpMomID(attribName, (CompID *) resVectorAttrib) ) {
- self->f_accelerationX = dataValue->f_vector.f_angle;
- self->f_accelerationY = dataValue->f_vector.f_magnitude;
- return kMNoCompErr;
- }
- else
- return kMUnableToComplyCompErr;
- }
-
-
- /* Adjust project-specific IDs
- */
-
- static MErr MCompAdaptIDs(MomentumComp *self, MObjectPtr *sourceStore, MObjectPtr *targetStore)
- {
- MTranslateID(kMTranslateEventID, sourceStore, targetStore, (MDataType *) &self->f_activateEvent);
- MTranslateID(kMTranslateEventID, sourceStore, targetStore, (MDataType *) &self->f_terminateEvent);
- return kMNoCompErr;
- }
-
-
- /* Momentum task
- */
-
- static MErr MomentumTask(MomentumComp *self, MTInfo *tinfo)
- {
- double deltaVelocityX, deltaVelocityY;
- double signX, signY;
- double tmpX, tmpY;
- double absVal;
- long globalTime, deltaTime;
-
- MGetGlobalTime(&globalTime);
- deltaTime = globalTime - self->f_timeStamp;
-
- deltaVelocityX = (double) deltaTime * self->f_accelerationX / (double) kMGlobalTimeConst;
- deltaVelocityY = (double) deltaTime * self->f_accelerationY / (double) kMGlobalTimeConst;
-
- tmpX = self->f_velocityX + deltaVelocityX;
- tmpY = self->f_velocityY + deltaVelocityY;
- signX = tmpX < 0.0 ? -1.0 : 1.0;
- signY = tmpY < 0.0 ? -1.0 : 1.0;
-
- MFabs(&absVal, tmpX);
- self->f_velocityX = absVal > self->f_terminalVelocity.f_value ?
- self->f_terminalVelocity.f_value * signX : tmpX;
- MFabs(&absVal, tmpY);
- self->f_velocityY = absVal > self->f_terminalVelocity.f_value ?
- self->f_terminalVelocity.f_value * signY : tmpY;
-
- if ( self->f_velocityX || self->f_velocityY ) {
- MDataType curPos;
- double dPosX, dPosY;
- MObjectRef *element;
-
- MInitPoint2D(curPos.f_point, 0, 0);
- MGetElement(&element);
- MGetElementAttribute(element, kMPositionAttrib, NULL, &curPos);
-
- dPosX = (double) curPos.f_point.f_value.PNTX + self->f_fractionalX;
- dPosY = (double) curPos.f_point.f_value.PNTY + self->f_fractionalY;
-
- curPos.f_point.f_value.PNTX = dPosX + self->f_velocityX;
- curPos.f_point.f_value.PNTY = dPosY + self->f_velocityY;
-
- self->f_fractionalX = dPosX + self->f_velocityX - curPos.f_point.f_value.PNTX;
- self->f_fractionalY = dPosY + self->f_velocityY - curPos.f_point.f_value.PNTY;
-
- MSetElementAttribute(element, kMPositionAttrib, NULL, &curPos);
- }
-
- self->f_timeStamp = globalTime;
- return kMNoCompErr;
- }
-